package auth

import (
	"beegoProject14/models/auth"
	"beegoProject14/utils"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"math"
	"strings"
	"time"
)

type RoleController struct {
	beego.Controller
}

func (c *RoleController) List() {

	// 数据库查询并传入前端
	o := orm.NewOrm()
	qs := o.QueryTable("sys_role")

	roles := []auth.Role{}
	qs.Filter("is_delete", 0).All(&roles)

	/*
		分页逻辑 ⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️
	*/

	// 每页显示数据-4条 (pagePerNum)
	pagePerNum := 5

	// 当前页 (currentPage)
	currentPage, err := c.GetInt("page")
	// 说明没有获取到当前页
	if err != nil {
		currentPage = 1 // 所以默认显示第一页
	}

	// 增加查询：
	offsetNum := pagePerNum * (currentPage - 1)

	// 总数据量
	count, _ := qs.Filter("is_delete", 0).Count()
	// 用户详细信息查询
	qs.Filter("is_delete", 0).Limit(pagePerNum).Offset(offsetNum).All(&roles)

	// 总页数 (count) =  总数据量 / 每页数据量   注：需要转换成int类型
	countPage := int(math.Ceil(float64(count) / float64(pagePerNum)))

	// 判断上一页
	prePage := 1
	if currentPage == 1 {
		prePage = 1
	} else if currentPage > 1 {
		// 上一页
		prePage = currentPage - 1
	}

	// 下一页
	nextPage := 1
	// 如果当前页小于总页数
	if currentPage < countPage {
		// 下一页 就等于 当前页+1
		nextPage = currentPage + 1
		// 如果当前页面大于等于总页数
	} else if currentPage >= countPage {
		// 下一页 就等于 当前页
		nextPage = currentPage
	}

	// 引用倒入到函数page.go
	page_map := utils.Paginator(currentPage, pagePerNum, count)

	c.Data["prePage"] = prePage         /* 上一页*/
	c.Data["nextPage"] = nextPage       /* 下一页 */
	c.Data["currentPage"] = currentPage /* 当前页 */
	c.Data["countPage"] = countPage
	c.Data["count"] = count
	c.Data["page_map"] = page_map
	/*
		分页逻辑 ⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️
	*/

	c.Data["roles"] = roles
	c.TplName = "auth/role-list.html"
}

func (c *RoleController) ToAdd() {

	c.TplName = "auth/role-add.html"

}

func (c *RoleController) DoAdd() {

	// 1
	role_name := c.GetString("role_name")
	desc := c.GetString("desc")
	is_active, _ := c.GetInt("is_active")

	// 3
	role := auth.Role{
		RoleName:   role_name,
		Desc:       desc,
		IsActive:   is_active,
		CreateTime: time.Now(),
	}

	// 2
	o := orm.NewOrm()
	_, err := o.Insert(&role)

	// 4
	message_map := map[string]interface{}{}

	// 5
	if err != nil {
		message_map["code"] = 10001
		message_map["msg"] = "添加数据出错，请重新添加"
	} else {
		message_map["code"] = 200
		message_map["msg"] = "添加成功"
	}

	// 6
	c.Data["json"] = message_map
	c.ServeJSON()
}

// ToRoleUser 角色用户配置
func (c *RoleController) ToRoleUser() {

	id, _ := c.GetInt("role_id")

	// 数据库查询初id对应的权限
	role := auth.Role{} // 单个ID
	o := orm.NewOrm()
	o.QueryTable("sys_role").Filter("id", id).One(&role)

	/*
		已绑定用户
	*/
	o.LoadRelated(&role, "User")

	/*
		未绑定用户，  所有用户减去已绑定等于未绑定 .Exclude("id__in", role.User)
	*/
	users := []auth.User{}
	/* 增加数据判断 有数据和无数据 */
	if len(role.User) > 0 { // 有绑定数据
		o.QueryTable("sys_user").Filter("is_delete", 0).Filter("is_active", 1).Exclude("id__in", role.User).All(&users)
	} else { // 没有绑定数据
		o.QueryTable("sys_user").Filter("is_delete", 0).Filter("is_active", 1).All(&users)
	}

	c.Data["role"] = role
	c.Data["users"] = users
	c.TplName = "auth/role-user-add.html"

}

// DoRoleUser 角色用户配置
func (c *RoleController) DoRoleUser() {

	roleId, _ := c.GetInt("role_id")
	userIds := c.GetString("user_ids")

	userIdArr := strings.Split(userIds, ",")

	o := orm.NewOrm()

	role := auth.Role{
		Id: roleId,
	}

	/* 查询出已绑定到数据 */
	m2m := o.QueryM2M(&role, "user")
	m2m.Clear()

	for _, userId := range userIdArr {
		user := auth.User{
			Id: utils.StrToInt(userId),
		}
		m2m := o.QueryM2M(&role, "User")
		m2m.Add(user)
	}

	c.Data["json"] = map[string]interface{}{
		"code": 200,
		"msg":  "添加成功",
	}
	c.ServeJSON()

}

// ToRoleAuth 角色权限配置
func (c *RoleController) ToRoleAuth() {

	// 1. 获取前端数据
	roleId, _ := c.GetInt("role_id")

	// 3. 初始化容器
	role := auth.Role{}

	// 2. 数据库
	o := orm.NewOrm()
	qs := o.QueryTable("sys_role")
	qs.Filter("id", roleId).One(&role)

	c.Data["role"] = role
	c.TplName = "auth/role-auth-add.html"
}

func (c *RoleController) GetAuthJson() {

	// 9.64 0. 前端获取 role_id
	roleId, _ := c.GetInt("role_id")

	// 1. 初始化数据库
	o := orm.NewOrm()
	qs := o.QueryTable("sys_auth")

	// 9.64 1. 已绑定的权限
	role := auth.Role{ // 查询
		Id: roleId,
	}
	o.LoadRelated(&role, "Auth") // 关联查询Auth
	// 只获取Id [11,14,16,21]
	authIdsHas := []int{}
	for _, authData := range role.Auth {
		authIdsHas = append(authIdsHas, authData.Id)
	}
	fmt.Println("所获取的 authIdsHas: ", authIdsHas)

	// 2 数查询存入容器 auths（所有的权限）
	auths := []auth.Auth{}
	qs.Filter("is_delete", 0).All(&auths)

	// 3 按照html展示的数据页面封装结构体
	authArrMap := []map[string]interface{}{}

	// 4. 循环过滤auths数据，并对应添加到数组内
	for _, authData := range auths {
		id := authData.Id
		pId := authData.Pid
		name := authData.AuthName

		// 7 增加首次展开open判断
		if pId == 0 {
			// 5. 数据传入
			authMap := map[string]interface{}{
				"id":   id,
				"pId":  pId,
				"name": name,
				"open": false,
			}
			// 6 追加写入
			authArrMap = append(authArrMap, authMap)
		} else {
			// 5. 数据传入
			authMap := map[string]interface{}{
				"id":   id,
				"pId":  pId,
				"name": name,
			}
			// 6 追加写入
			authArrMap = append(authArrMap, authMap)
		}

	}
	// 增加字典 9.64 3
	authMaps := map[string]interface{}{}
	authMaps["auth_arr_map"] = authArrMap
	authMaps["auth_ids_has"] = authIdsHas
	c.Data["json"] = authMaps

	// c.Data["json"] = authArrMap
	c.ServeJSON()
}

// DoRoleAuth  角色权限配置
func (c *RoleController) DoRoleAuth() {

	// 1 后端获取
	roleId, _ := c.GetInt("role_id")
	authIds := c.GetString("auth_ids")

	// 2 切割
	/*newAuthIds := authIds[1 : len(authIds)-1]*/
	idArr := strings.Split(authIds, ",")

	// 3 数据库操作
	o := orm.NewOrm()
	role := auth.Role{
		Id: roleId,
	}
	// 4 关联查询
	m2m := o.QueryM2M(&role, "Auth")
	m2m.Clear()

	for _, authId := range idArr {
		authId_int := utils.StrToInt(authId)

		// 5 不能有空格
		if authId_int != 0 {
			authData := auth.Auth{
				Id: authId_int,
			}
			m2m = o.QueryM2M(&role, "Auth")
			m2m.Add(authData)
		}
	}

	// 返回到前端ajax
	c.Data["json"] = map[string]interface{}{
		"code": 200,
		"msg":  "添加成功",
	}
	c.ServeJSON()

}
